package com.htfyun.ft.fragment.factory;

import android.content.Context;
import android.os.Bundle;
import android.os.Message;
import android.view.View;
import android.widget.TextView;

import com.htfyun.ft.FTApplication;
import com.htfyun.ft.R;
import com.htfyun.ft.utils.DebugLog;
import com.htfyun.serialport.ServoSingleton;
import com.htfyun.serialport.uartservo.IServoControl;
import com.htfyun.serialport.uartservo.OnServoListener;
import com.htfyun.serialport.uartservo.ServoControlAttr;
import com.htfyun.serialport.uartservo.ServoErrorAttr;
import com.htfyun.serialport.uartservo.ServoInterestedInfo;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import androidx.annotation.Nullable;

public class FragmentServo extends FactoryBaseFragment implements
        View.OnClickListener,
        OnServoListener {

    private final static int DefaultAngularVelocity = 50;
    private final static int DEFAULT_POSITION_DELTA = 5;//误差 5 度

    private TextView txtFirmwareVersion;
    private TextView txtAngleArea;
    private TextView txtAngularVelocity;
    private TextView txtFeedbackTime;
    private TextView txtPosition;
    private TextView txtMoveStatus;
    private TextView txtErrorStatus;

    private TextView txtPositionDelta;


    @Override
    protected int getLayoutRes() {
        return R.layout.fragment_factory_servo;
    }

    @Override
    protected void onInitView(@Nullable Bundle savedInstanceState) {
        super.onInitView(savedInstanceState);
        initView();

        initBtn(R.id.btnStop);
        initBtn(R.id.btnSetZero);
        initBtn(R.id.btnTurnLeft);
        initBtn(R.id.btnTurnMiddle);
        initBtn(R.id.btnTurnRight);
    }

    private void initView() {

        txtFirmwareVersion = (TextView) findViewById(R.id.txtFirmwareVersion);
        txtAngleArea = (TextView) findViewById(R.id.txtAngleArea);
        txtAngularVelocity = (TextView) findViewById(R.id.txtAngularVelocity);
        txtFeedbackTime = (TextView) findViewById(R.id.txtFeedbackTime);
        txtPosition = (TextView) findViewById(R.id.txtPosition);
        txtMoveStatus = (TextView) findViewById(R.id.txtMoveStatus);
        txtErrorStatus = (TextView) findViewById(R.id.txtErrorStatus);

        txtErrorStatus.setVisibility(View.INVISIBLE);

        txtPositionDelta = (TextView) findViewById(R.id.txtPositionDelta);
        txtPositionDelta.setText(getString(R.string.test_servo_position_delta, DEFAULT_POSITION_DELTA));

    }

    private void initBtn(int resId) {
        View btn = findViewById(resId);
        if (btn != null) {
            btn.setOnClickListener(this);
        }
    }

    @Override
    protected void onInvisible() {
        super.onInvisible();
        DebugLog.e("onInvisible = ");

        getHandler().removeMessages(MSG_UPDATE_TXT);
        getHandler().removeMessages(MSG_ERROR_HAPPENED);

        servoDeInit();

    }

    @Override
    protected void onVisible() {
        super.onVisible();

        DebugLog.e("onVisible = ");

        servoInit();

    }

    private void servoDeInit(){
        ServoSingleton.INSTANCE.getServoControl().unregisterServoListener(this);
        ServoSingleton.INSTANCE.getServoControl().servoStop();
    }

    private void servoInit() {
        ServoSingleton.INSTANCE.getServoControl().servoStop();
        ServoSingleton.INSTANCE.getServoControl().registerServoListener(this);

        servoInitSetAndGet();
        servoInitSetAndGet();

    }

    private void servoInitSetAndGet() {
        ServoSingleton.INSTANCE.getServoControl().setAngularVelocity(DefaultAngularVelocity);
        ServoSingleton.INSTANCE.getServoControl().setFeedbackTime_100ms(3);

        ServoSingleton.INSTANCE.getServoControl().getAngleAreaMax();
        ServoSingleton.INSTANCE.getServoControl().getAngleAreaMin();
        ServoSingleton.INSTANCE.getServoControl().getPosition();
        ServoSingleton.INSTANCE.getServoControl().getFeedbackTime_100ms();
        ServoSingleton.INSTANCE.getServoControl().getFirmwareVersion();
    }

    private int getPositionMiddle(ServoInterestedInfo info) {
        int min = info.getAngleAreaMin();
        int max = info.getAngleAreaMax();
        return (min + max) / 2;
    }

    @Override
    public void onClick(View v) {

        switch (v.getId()) {
            case R.id.btnStop:
                ServoSingleton.INSTANCE.getServoControl().servoStop();
                break;
            case R.id.btnSetZero:
                ServoInterestedInfo info = getServoControl().getServoInterestedInfo();
                getServoControl().servoStop();
                getServoControl().setZeroForServo();

                getHandler().postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        getServoControl().getPosition();
                    }
                }, 300);
                break;
            case R.id.btnTurnLeft:
                getServoControl().turnRight();
                break;
            case R.id.btnTurnMiddle:
                getServoControl().setPosition(getPositionMiddle(getServoControl().getServoInterestedInfo()));
                break;
            case R.id.btnTurnRight:
                getServoControl().turnLeft();
                break;
        }
    }

    @Override
    public void onServoListener(List<ServoErrorAttr> errorAttrList, ServoControlAttr controlAttr, ServoControlAttr.Instruction instruction, ServoInterestedInfo info) {

        if (errorAttrList != null && !errorAttrList.isEmpty()) {
            StringBuilder errSB = new StringBuilder();
            for (ServoErrorAttr errorAttr : errorAttrList) {
                DebugLog.e(" errorAttr = " + errorAttr);
                errSB.append(errorAttr.toString());
                errSB.append(";");
            }

            getHandler().obtainMessage(MSG_ERROR_HAPPENED, errSB.toString()).sendToTarget();

        }

        if (info == null) {
            DebugLog.e(" ServoInterestedInfo is null");
            return;
        }

        getHandler().obtainMessage(MSG_UPDATE_TXT, info).sendToTarget();

    }

    private IServoControl getServoControl() {
        return ServoSingleton.INSTANCE.getServoControl();
    }

    private void updateTxt(ServoInterestedInfo info) {

        txtFirmwareVersion.setText(getString(R.string.servo_firmware_version, info.getFirmwareVersion()));

        txtAngleArea.setText(getString(R.string.servo_show_info,
                info.getAngleAreaMin(),
                info.getAngleAreaMax()));

        txtAngularVelocity.setText(getString(R.string.status_current_angular_velocity, info.getAngularVelocity()));
        txtFeedbackTime.setText(getString(R.string.status_feedback_time, info.getFeedbackTime_100ms()));

        txtPosition.setText(getString(R.string.status_current_position, info.getPosition()));

        String yes = getString(R.string.yes);
        String no = getString(R.string.no);
        txtMoveStatus.setText(getString(R.string.status_moving, info.isMoving() ? yes : no));

    }

    private final int MSG_UPDATE_TXT = 100;
    private final int MSG_ERROR_HAPPENED = 101;

    @Override
    protected void handleMessage(Message msg) {
        switch (msg.what) {
            case MSG_UPDATE_TXT:
                if (msg.obj instanceof ServoInterestedInfo) {
                    updateTxt((ServoInterestedInfo) msg.obj);
                }
                break;
            case MSG_ERROR_HAPPENED:
                if (msg.obj instanceof String) {

                    txtErrorStatus.setVisibility(View.VISIBLE);
                    txtErrorStatus.setText(getString(R.string.servo_error_happened, msg.obj));

                }
                break;
        }

    }

}
